package com.zjht.gmcc.bean;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.zjht.gmcc.bean.util.LogUtil;
import com.zjht.gmcc.bean.util.Menu;
import com.zjht.gmcc.bean.util.MyFormat;
import com.zjht.gmcc.bean.util.MyJDBC;
import com.zjht.gmcc.bean.util.MySession;

public abstract class BaseServlet extends HttpServlet {
	private static final long serialVersionUID = 4474764798791974692L;
	public static final String MENU = "menu";// 菜单ID
	public static final String TRANSACTION = "transation";// 是否需要数据库事务管理
	public static final String NOTRANSACTION = "false";// 不需要数据库事务管理

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAll(request, response);
	}

	private void doAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("GBK");
		response.setCharacterEncoding("GBK");
		response.setContentType("text/html;charset=GBK");  
		PrintWriter out = response.getWriter();
		String menu = getServletConfig().getInitParameter(MENU);
		boolean hasTransaction = !NOTRANSACTION.equals(getServletConfig().getInitParameter(TRANSACTION));
		if (!Menu.NONE.equals(menu)) {
			if (!MySession.ValidSessionServlet(request, out, menu))
				return;
		}
		MyJDBC myJDBC = null;
		try {
			myJDBC = new MyJDBC();
			if (hasTransaction)
				myJDBC.beginTransaction();
			HttpSession session = request.getSession();
			boolean ok = process(request, response, session, out, myJDBC, menu);
			if (hasTransaction) {
				boolean isAvatar = session.getAttribute(MySession.USER_AVATAR) != null;
				if (ok && !isAvatar)
					myJDBC.commitTransaction();
				else
					myJDBC.rollbackTransaction();
			}

		} catch (Exception e) {
			if (hasTransaction)
				myJDBC.rollbackTransaction();
			e.printStackTrace();
			expAlert(request, out, menu);// 向用户提示异常错误提醒
		} finally {
			MyJDBC.close(myJDBC);
			out.flush();
			out.close();
		}
	}

	/**
	 * 业务处理
	 * @author dyh 2009-11-15
	 * @return true:表示可以提交事务；false表示出错，需要回滚事务
	 * @throws Exception
	 */
	protected abstract boolean process(HttpServletRequest request, HttpServletResponse response, HttpSession session, PrintWriter out, MyJDBC myJDBC,
			String menu) throws Exception;

	public void forward(HttpServletRequest request, HttpServletResponse response, String url) {
		RequestDispatcher rd = getServletContext().getRequestDispatcher(url);
		try {
			rd.forward(request, response);
		} catch (ServletException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void redirect(HttpServletRequest request, HttpServletResponse response, String url) {
		try {
			response.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 处理完成后弹出alert提示框
	 * @author dyh 2009-11-15
	 * @param alertmsg 提示框内容
	 */
	protected void alert(PrintWriter out, String alertmsg) {
		alert(out, alertmsg, null);
	}

	/**
	 * 页面提交的参数为空，弹出警告框
	 * @author dyh 2010-06-11
	 */
	protected void alertNullParameter(PrintWriter out) {
		alert(out, MySession.MSG_NULL);
	}

	/**
	 * 处理完成后弹出alert提示框。如果打开的是modal窗口，则刷新父窗口URL，否则刷新本窗口URL
	 * @author dyh 2009-11-15
	 * @param alertmsg 提示框内容
	 * @param url 刷新窗口的URL
	 */
	protected void alert(PrintWriter out, String alertmsg, String url) {
		alertOK(out, alertmsg, MySession.getURLScript(url));
	}

	/**
	 * 处理完成后弹出alert提示框，并返回returnvalue
	 * @author dyh 2009-11-21
	 * @param alertmsg 提示框内容
	 * @param returnvalue 返回父窗口的值
	 */
	protected void alertAndReturnValue(PrintWriter out, String alertmsg, String returnvalue) {
		alertOK(out, alertmsg, (!MyFormat.isStrNull(returnvalue) ? "window.returnValue='" + returnvalue
				+ "';if(parent)parent.hideDiv();window.close();" : null));
	}

	/**
	 * 处理完成后弹出alert提示框，并执行otherscript
	 * @author dyh 2009-11-15
	 * @param alertmsg 提示框内容
	 * @param otherscript 其他脚本
	 */
	protected void alertOK(PrintWriter out, String alertmsg, String otherscript) {
		out.print(MySession.getScript(alertmsg, otherscript));
	}

	/**
	 * 系统发生异常时alert提示框(错误代码为：00#menuid)
	 * @author dyh 2009-11-15
	 */
	private void expAlert(HttpServletRequest request, PrintWriter out, String menu) {
		String errcode = LogUtil.getErrCode(LogUtil.ERRSOURCE_SERVLET, LogUtil.ERRTYPE_SYS, menu);
		alert(out, MySession.getExpMsg(errcode));
		LogUtil.logErr(request, errcode);
	}

	/**
	 * 系统发生逻辑异常时alert提示框(错误代码为：01#menuid)
	 * @author dyh 2009-11-15
	 * @param alertmsg 逻辑错误名称(无须写“对不起”之类的字类)
	 * @param url 需要刷新的页面URL（如果不需要刷新，则为null）
	 */
	public void errAlert(HttpServletRequest request, PrintWriter out, String menu, String alertmsg, String url) {
		String errcode = LogUtil.getErrCode(LogUtil.ERRSOURCE_SERVLET, LogUtil.ERRTYPE_USER, menu);
		alert(out, MySession.getErrMsg(alertmsg, errcode), url);
		LogUtil.logErr(request, errcode);
	}

	/**
	 * 系统发生逻辑异常时alert提示框(错误代码为：01#menuid)(不需要刷新url)
	 * @author dyh 2009-11-15
	 * @param alertmsg 逻辑错误名称(无须写“对不起”之类的字类)
	 */
	public void errAlert(HttpServletRequest request, PrintWriter out, String menu, String alertmsg) {
		errAlert(request, out, menu, alertmsg, null);
	}

}